package com.ynkbny.service.impl;


import com.alibaba.fastjson.JSON;
import com.alibaba.fastjson.JSONArray;
import com.alibaba.fastjson.JSONObject;
import com.baomidou.mybatisplus.core.conditions.query.LambdaQueryWrapper;
import com.baomidou.mybatisplus.core.conditions.query.QueryWrapper;
import com.baomidou.mybatisplus.extension.plugins.pagination.Page;
import com.baomidou.mybatisplus.extension.service.impl.ServiceImpl;
import com.ynkbny.base.PageResult;
import com.ynkbny.domain.*;
import com.ynkbny.domain.dto.TEpDataCollectConfigureDTO;
import com.ynkbny.domain.excel.DatacollectconfigureExportVO;
import com.ynkbny.domain.excel.TEpTotalEnergyExportVO;
import com.ynkbny.domain.pojo.EnterpriseGetNameVO;
import com.ynkbny.domain.pojo.TEpDataCollectConfigureAddVO;
import com.ynkbny.lgapi.YnBk;
import com.ynkbny.mapper.EnterpriseMapper;
import com.ynkbny.mapper.TEpDataCollectConfigureMapper;
import com.ynkbny.service.*;
import com.ynkbny.service.outsideinterface.MyClient;
import com.ynkbny.tasks.UploadDataEnergyToDay;
import com.ynkbny.util.*;
import lombok.extern.slf4j.Slf4j;
import lombok.var;
import org.jetbrains.annotations.NotNull;
import org.slf4j.Logger;
import org.slf4j.LoggerFactory;
import org.springframework.beans.BeanUtils;
import org.springframework.beans.factory.annotation.Value;
import org.springframework.stereotype.Service;
import org.springframework.util.ObjectUtils;

import javax.annotation.Resource;
import java.io.IOException;
import java.util.*;
import java.util.stream.Collectors;

/**
* @author YY
* @description 针对表【t_ep_datacollectconfigure(用能单位数据采集配置项信息 用能单位数据采集配置项信息)】的数据库操作Service实现
* @createDate 2023-07-05 17:56:35
*/
@Slf4j
@Service
public class TEpDataCollectConfigureServiceImpl extends ServiceImpl<TEpDataCollectConfigureMapper, TEpDataCollectConfigureDTO>
    implements TEpDataCollectConfigureService {

    private static final Logger log = LoggerFactory.getLogger(UploadDataEnergyToDay.class);

    @Value("${laoGouWeb.datacollectconfigure}")
    private String datacollectconfigure;

    @Resource
    private MyClient myClient;

    @Resource
    private TEpUploadTimeService uploadTimeService;

    @Resource
    private TEpDataCollectConfigureMapper tEpDatacollectconfigureMapper;

    @Resource
    private EnterpriseMapper enterpriseMapper;

    @Resource
    private YnBk ynBk;

    @Resource
    private ConversionCoefficientService conversionCoefficientService;

    @Resource
    private EnergySubstanceCodesService energySubstanceCodesService;

    @Resource
    private TokenService tokenService;

    @Resource
    private DataPushUtil dataPushUtil;

    @Value("${measurement.pushDataCollectConfigure}")
    private  String pushUrl;

    @Resource
    private UserRoleUtil<TEpDataCollectConfigureDTO> userRoleUtil;

    /**
     * 分页查询
     * @param pageNum 页码
     * @param pageSize 单页条数
     * @param conditionJson 查询条件
     */
    @Override
    public Page<TEpDataCollectConfigureDTO> selectByPage(Long pageNum, Long pageSize, String conditionJson) {
        Page<TEpDataCollectConfigureDTO> pageParam = new Page<>(pageNum,pageSize);
        QueryWrapper<TEpDataCollectConfigureDTO> queryWrapper = SearchUtil.parseWhereSql(null,null,conditionJson);
//        Page<TEpDataCollectConfigureDTO> pageData = tEpDatacollectconfigureMapper.selectPage(pageParam, queryWrapper);
        Page<TEpDataCollectConfigureDTO> pageList = userRoleUtil.getPageList(pageParam, queryWrapper, this.baseMapper);
        return pageList;
    }

    /**
     * 根据企业信用代码查询采集配置项列表
     * @param pageNum 页码
     * @param pageSize 单页数量
     * @param condition 查询条件
     * @return
     */
    @Override
    public PageResult<TEpDataCollectConfigureDTO> getListByEnterpriseCode(Long pageNum, Long pageSize, String condition) {
        Page<TEpDataCollectConfigureDTO> page=new Page<>(pageNum,pageSize);
        String enterpriseCode = null;
        QueryWrapper<TEpDataCollectConfigureDTO> queryWrapper = null;
        Page<TEpDataCollectConfigureDTO> pageList = null;
        Enterprise enterprise=enterpriseMapper.selectById(condition);
        if (enterprise != null) {
            enterpriseCode = enterprise.getEnterpriseCode();
            queryWrapper = new QueryWrapper<TEpDataCollectConfigureDTO>().eq("enterprise_code",enterpriseCode);
            pageList = this.baseMapper.selectPage(page, queryWrapper);
            return new PageResult<>(pageList);
        }else {
            return null;
        }
    }

    /**
     * 通过id查询 用能单位数据采集配置项信息
     * @param id id
     */
    @Override
    public TEpDataCollectConfigureDTO getOneById(String id) {
        TEpDataCollectConfigureDTO oneData = getById(id);
        return oneData;
    }

    /**
     * 修改指定id的 用能单位数据采集配置项信息
     * @param tEpDataCollectConfigureDTO 实体类对象
     */
    @Override
    public boolean updateOneById(TEpDataCollectConfigureDTO tEpDataCollectConfigureDTO) {
        boolean isUpdate = updateById(tEpDataCollectConfigureDTO);
        return isUpdate;
    }

    /**
     * 用能单位数据采集配置项信息添加结果回写
     * @param tEpDataCollectConfigureList 要修改的实体集合
     */
    @Override
    public int updateDataCollectConfigure(List<TEpDataCollectConfigureDTO> tEpDataCollectConfigureList) {
        int count = 0;
        for (TEpDataCollectConfigureDTO temp : tEpDataCollectConfigureList){
            int update = tEpDatacollectconfigureMapper.updateById(temp);
            count += update;
        }
        return count;
    }

    /**
     * 通实体字段进行查询(and连接)
     * @param tEpDataCollectConfigureDTO 实体对象
     */
    @Override
    public List<TEpDataCollectConfigureDTO> selectByEntityField(TEpDataCollectConfigureDTO tEpDataCollectConfigureDTO) {
        List<TEpDataCollectConfigureDTO> list = tEpDatacollectconfigureMapper.selectByEntityField(tEpDataCollectConfigureDTO);
        return list;
    }

    @Override
    public boolean uploadOneById(TEpDataCollectConfigureDTO dto) {
        // 获取token
        String token = uploadTimeService.getToken(dto.getEnterpriseCode());
        if ("".equals(token)){
            log.info("获取token失败");
            throw new BusinessException(RespStaticEnum.FAIL,"获取token失败");
        }

        TEpDataCollectConfigureAddVO vo = new TEpDataCollectConfigureAddVO();
        BeanUtils.copyProperties(dto,vo);
        JSONObject jsonObject = myClient.dataCollectConfigureAdd(token, vo);
        if (!"200".equals(jsonObject.getString("responseCode"))){
            throw new BusinessException(RespStaticEnum.FAIL,jsonObject.toJSONString());
        }
        dto.setDataIndex(jsonObject.getJSONObject("data").getString("dataIndex"));
        Date date = new Date();
        dto.setUpdateTime(date);
        int updateById = tEpDatacollectconfigureMapper.updateById(dto);
        log.info("成功更新{}条采集配置项",updateById);
        log.info(jsonObject.toJSONString());
        return true;
    }

    @Override
    public List<TEpDataCollectConfigureDTO> getByEnterpriseCodeList(String enterpriseCode,String energyTypeCode){
        return tEpDatacollectconfigureMapper.getByEnterpriseCodeList(enterpriseCode,energyTypeCode);
    }


    /**
     * 从老狗平台拉取采集配置项并更新或插入数据
     * @Author YY
     * @param proId 项目id，也是数据采集配置项的data_id
     * @return boolean
     */
    @Override
    public boolean saveOrUpdateBatchData(Integer proId){
        String gouWebToken = tokenService.getLaoGouWebToken();

        Enterprise enterprise = enterpriseMapper.selectById(proId);
        String enterpriseCode = enterprise.getEnterpriseCode();

        JSONObject result = ynBk.getDataCollectConfigure("ssid="+gouWebToken,proId);
        List<TEpDataCollectConfigureDTO> dataList = new ArrayList<>();
        JSONArray rows = result.getJSONArray("rows");
        System.out.println(rows);

        List<EnergySubstanceCodes> energySubstanceCodesList = energySubstanceCodesService.list();
        Map<String,List<String>> energySubstanceCodesMap = new HashMap<>(energySubstanceCodesList.size());
        energySubstanceCodesList.forEach(n -> energySubstanceCodesMap.put(n.getCode(), Arrays.asList(n.getCollectUnit(),n.getQualityUnit())));

        List<ConversionCoefficient> list = conversionCoefficientService.list();
        Map<String,List<String>> map = new HashMap<>(list.size());
        list.forEach(n -> map.put(n.getCode(), Arrays.asList(n.getCollectUnit(),n.getQualityUnit())));

        LambdaQueryWrapper<TEpDataCollectConfigureDTO> lambdaQueryWrapper = new LambdaQueryWrapper<>();
        lambdaQueryWrapper.eq(TEpDataCollectConfigureDTO::getEnterpriseCode,enterpriseCode);
        List<TEpDataCollectConfigureDTO> dtoList = this.list(lambdaQueryWrapper);

        Map<String,TEpDataCollectConfigureDTO> dtoMap = new HashMap<>(dtoList.size());
        dtoList.forEach(n -> dtoMap.put(n.getDataCode(),n));

        for (Object row : rows) {
            JSONObject data = (JSONObject) JSON.toJSON(row);
            // 根据采集数据项编码
            TEpDataCollectConfigureDTO dto = dtoMap.getOrDefault(data.getString("colleCode"),new TEpDataCollectConfigureDTO());
            // 赋值
            dto.setEnterpriseCode(enterpriseCode);
            //采集数据项指标名称
            dto.setCollectitemName(data.getString("colleName"));
            //采集数据项编码
            dto.setDataCode(data.getString("colleCode"));
            //生产工序
            dto.setProcessCode(data.getString("prodWork"));
            //工序单元
            dto.setProcessUnitCode(data.getString("workUnit"));
            //重点耗能设备类型
            dto.setEquipmentCode(data.getString("devTy"));
            //重点耗能设备编号
            dto.setEquipmentUnitCode(data.getString("devCode"));
            //采集对象类型
            dto.setEnergyClassCode(data.getString("colleTy"));
            //能源分类 + 分项
            dto.setEnergyTypeCode(data.getString("energyItem"));
            //用途编码
            dto.setDataUsageCode(data.getString("purposeCode"));
            //数据采集来源
            dto.setInputType(data.getString("colleBase"));
            //数据最大值
            dto.setDataValueMax(data.getString("valMax"));
            //数据最小值
            dto.setDataValueMin(data.getString("valMin"));
            //采集频率(0：实时 1：日 2：月 3：年)
            dto.setStatType(data.getString("colleFrequency"));
            //采集系统名称
            dto.setCollectSystemName(data.getString("colleSyname"));
            //范围(1 ：全厂 2 ：生产工序 3 ：生产工序单元 4 ：重点耗能设备)
            dto.setScope(data.getString("rg"));
            //备注
            dto.setRemark(data.getString("remark"));
            //更新时间
            dto.setUpdateTime(new Date());
            //设置折标系数单位和上传数据单位
            if (data.getString("colleTy").equals("03")){
                List<String> unitList = energySubstanceCodesMap.get(data.getString("energyItem"));
                dto.setConvertRationUnit(ObjectUtils.isEmpty(unitList) ? null : unitList.get(0));
                dto.setDataValueUnit(ObjectUtils.isEmpty(unitList) ? null : unitList.get(1));
            }else {
                List<String> unitList = map.get(data.getString("energyItem"));
                dto.setConvertRationUnit(ObjectUtils.isEmpty(unitList) ? null : unitList.get(0));
                dto.setDataValueUnit(ObjectUtils.isEmpty(unitList) ? null : unitList.get(1));
            }
            //平台服务版本
            dto.setRegVersion("1.0版本");
            //基础数据版本
            dto.setDicVersion("1.0版本");

            BeanUtils.copyProperties(dto,dto);
            dataList.add(dto);
        }
        return this.saveOrUpdateBatch(dataList);
    }


    /**
     * excel导入 模板
     *
     * @author : juzipi123
     * @throws IOException 异常
     * @return 结果
     */
    @Override
    public List<TEpTotalEnergyExportVO> exportExcelTemplate(String enterpriseCode) {
        return tEpDatacollectconfigureMapper.selectExportExcelTemplate(enterpriseCode);
    }

    /**
     * excel导出 模板 V2
     *
     * @author : juzipi123
     * @param enterpriseCode  统一社会信用代码
     * @param statDate 数据统计时间
     * @param inputType 数据采集类型(1：管理信息系统 2：生产监控管理系统 3：分布式控制系统 4：现场仪表 5：手工填报 6：能源供应单位 7：其他)
     * @return 导出文件
     */
    @Override
    public List<DatacollectconfigureExportVO> exportExcelTemplateV2(String enterpriseCode, String statDate, String inputType) {
        List<TEpTotalEnergyExportVO> tEpTotalEnergyExportVOS
                = tEpDatacollectconfigureMapper.selectExportExcelTemplateV2(enterpriseCode, inputType);

        ArrayList<DatacollectconfigureExportVO> list = new ArrayList<>();
        for (TEpTotalEnergyExportVO tEpTotalEnergyExportVO :tEpTotalEnergyExportVOS){
            DatacollectconfigureExportVO datacollectconfigureExportVO = new DatacollectconfigureExportVO();
            BeanUtils.copyProperties(tEpTotalEnergyExportVO,datacollectconfigureExportVO);

            //数据统计时间
            datacollectconfigureExportVO.setStatDate(statDate);

            list.add(datacollectconfigureExportVO);
        }
        return list;
    }

    @Override
    public void getDataForLaoGou(String token, @NotNull EnterpriseGetNameVO enterpriseGetNameVO) {
        Integer proId = Integer.valueOf(enterpriseGetNameVO.getEnterpriseId());
        String enterpriseCode = enterpriseGetNameVO.getEnterpriseCode();
        JSONObject jsonObject = ynBk.getDataForLaoGou(datacollectconfigure, token, proId);
        if (jsonObject.getInteger("code") == 200) {
            List<Map<String, Object>> maps = (List<Map<String, Object>>) JSONArray.parse(jsonObject.getString("rows"));
            // 原数据map转bean 对应关系
            var list = ConvertBeanUtil.convertDataCollectCfg(maps, enterpriseCode);
            list.forEach(n -> {
                n.setRegVersion("1.0版本");
                n.setDicVersion("1.0版本");
            });
            var lambdaQueryWrapper = new LambdaQueryWrapper<TEpDataCollectConfigureDTO>();
            lambdaQueryWrapper.eq(TEpDataCollectConfigureDTO::getEnterpriseCode, enterpriseCode);
            var oldList = this.list(lambdaQueryWrapper);

            var editList = new ArrayList<TEpDataCollectConfigureDTO>();

            var iterator = list.iterator();
            while (iterator.hasNext()) {
                var oldIterator = oldList.iterator();
                var temp = iterator.next();
                while (oldIterator.hasNext()) {
                    var old = oldIterator.next();
                    if (temp.getDataId().equals(old.getDataId())) {
                        editList.add(temp);
                        oldIterator.remove();
                        iterator.remove();
                        break;
                    }
                }
            }
            if (!list.isEmpty()) {
                this.saveBatch(list);
            }
            if (!editList.isEmpty()) {
                this.updateBatchById(editList);
            }
            if (!oldList.isEmpty()) {
                this.removeBatchByIds(oldList.stream().map(TEpDataCollectConfigureDTO::getDataId).collect(Collectors.toList()));
            }
        }
    }

    /**
     * 上传数据
     *
     * @param enterpriseCode 社会信用代码
     * @param token  AK
     */
    @Override
    public void pushData(String enterpriseCode, String token) {
        this.listByMap(new HashMap<String, Object>() {{
            put("enterprise_code", enterpriseCode);
        }}).forEach(object -> {
            try {
                this.updateById(this.entityClass.cast(dataPushUtil.pushData(token, object, pushUrl)));
            } catch (Exception e) {
                log.info("数据推送失败", e);
            }
        });
    }
}




